﻿using SIPSorcery.SIP;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ACD
{
    public struct Session
    {
        public string sessionTag;
        public string agentNumber;
        public string message;
        public string localTag;
        public string remoteNumber1;
        public string remoteNumber2;
        public string remoteNumber3;
    }
    public struct Agent
    {
        public string agentNumber;
        public string status;
        public string lastCall1;
        public string lastCall2;
        public string lastCall3;
        public string lastMessage;
    }
    public struct Call
    {
        public string remoteNumber;
        public string message;
    }
    public static class Vars
    {
        public static SIP? sip;
        public static string sipUser;
        public static string sipPassword;
        public static string sipServerUri;
        public static string sipProxyUri;
        public static int expiry;
        public static string sipSignUpUrl;
        public static SIP? sipOut;
        public static string sipUserOut;
        public static string sipPasswordOut;
        public static string sipServerUriOut;
        public static string sipProxyUriOut;
        public static int expiryOut;
        public static string sipSignUpUrlOut;

        public static Agent[] agent = new Agent[20];
        public static int agentCount = 0;
        public static Session[] session = new Session[20];
        public static int sessionCount = 0;



        public static void Init()
        {
            ReadConfig();
            sip = new SIP();
            sip.StartUp(sipUser, sipPassword, sipServerUri, sipProxyUri, expiry, sipSignUpUrl);
            sipOut = new SIP();
            sipOut.StartUp(sipUserOut, sipPasswordOut, sipServerUriOut, sipProxyUriOut, expiryOut, sipSignUpUrlOut);

            sip.OnRegisterSuccessEvent += () =>
            {
                if (!sip.isListen)
                {
                    Thread t1 = new Thread(new ThreadStart(sip.ACDListen));
                    t1.IsBackground = true;
                    t1.Start();
                }
                if (!sip.isReceiveMsg)
                {
                    Thread t2 = new Thread(new ThreadStart(sip.ReceiveMsg));
                    t2.IsBackground = true;
                    t2.Start();
                }
            };
            sip.Register();

            sipOut.OnRegisterSuccessEvent += () =>
            {
                if (!sipOut.isReceiveMsg)
                {
                    Thread t3 = new Thread(new ThreadStart(sipOut.ReceiveMsg));
                    t3.IsBackground = true;
                    t3.Start();
                }
            };
            sipOut.Register();

            sip.OnACDAllocateSuccessEvent += (acdSession) =>
            {
                session[sessionCount].sessionTag = Guid.NewGuid().ToString();
                session[sessionCount].agentNumber = acdSession.agentNumber;
                session[sessionCount].message = acdSession.message;
                session[sessionCount].localTag = acdSession.localTag;
                session[sessionCount].remoteNumber1 = acdSession.remoteNumber;
                session[sessionCount].remoteNumber2 = "";
                session[sessionCount].remoteNumber3 = "";
                if (session[sessionCount].message != "")
                {
                    sipOut.SendMsg(acdSession.remoteNumber, "flag:Tag=" + session[sessionCount].sessionTag + ";LocalTag=" + session[sessionCount].localTag+";");
                    /* 发短信在这写*/
                }

                for (int i = 0; i < agentCount; i++)
                {
                    if (agent[i].agentNumber == acdSession.agentNumber)
                    {
                        agent[i].status = "Busy";
                        string lastMessage = "";
                        for (int j = 0; j < agentCount; j++)
                        {
                            if (session[sessionCount].remoteNumber1 == agent[j].lastCall1 || session[sessionCount].remoteNumber1 == agent[j].lastCall2 || session[sessionCount].remoteNumber1 == agent[j].lastCall3)
                            { 
                                lastMessage = agent[j].lastMessage;
                                break;
                            }
                        }
                        if (lastMessage != "")
                        {
                            sip.SendMsg(acdSession.agentNumber, "LastMessage=" + lastMessage + ";");
                        }
                        break;
                    }
                }
                sessionCount++;
                Show();
            };
            sip.OnACDListChangedEvent += () => { Show(); };
            sip.OnReceiveMsgEvent += (sipRequest) =>
            {
                // 内线收到的消息为坐席的登录/空闲/注销,例如UnRegister:Number=1001
                if (sipRequest.Body.Contains("UnRegister:"))
                {
                    string agentNumber = sipRequest.Body.Split("Number=")[1].Split(";")[0];
                    for (int i = 0; i < agentCount; i++)
                    {
                        if (agent[i].agentNumber == agentNumber)
                        {
                            for (int j = i; j < agentCount - 1; j++)
                            {
                                agent[j] = agent[j + 1];
                            }
                            agentCount--;
                            sip.RemoveAgent(agentNumber);
                            break;
                        }
                    }
                    Show();
                }
                else if (sipRequest.Body.Contains("Register") || sipRequest.Body.Contains("Free:"))
                {
                    string agentNumber = sipRequest.Body.Split("Number=")[1].Split(";")[0];
                    AgentSetFree(agentNumber,sipRequest.Body);
                    Show();
                }
                else if (sipRequest.Body.Contains("Out:"))
                {
                    //找到对应的Session,然后把消息发送给Session的RemoteNumber1
                    for (int i = 0; i < sessionCount; i++)
                    {
                        if (sipRequest.Body.Split("Out:Number=")[1].Split(";")[0] == session[i].agentNumber)
                        {
                            sipOut.SendMsg(session[i].remoteNumber1, "Tag=" + session[i].sessionTag + ";" + sipRequest.Body.Split(";")[1].Split(";")[0] +";");
                            break;
                        }
                    }
                }
            };
            sipOut.OnReceiveMsgEvent += (sipRequest) =>
            {
                if (!sipRequest.Body.Contains("Tag=")) return;
                // 根据Tag找到Session,然后把消息发送给Session的Agent
                if (sipRequest.Body.Contains("Chat=") || sipRequest.Body.Contains("RealTimeMessage="))
                {
                    string tag = sipRequest.Body.Split("Tag=")[1].Split(";")[0];
                    for (int i = 0; i < sessionCount; i++)
                    {
                        if (session[i].sessionTag == tag)
                        {
                            sip.SendMsg(session[i].agentNumber, sipRequest.Body+";");
                            break;
                        }
                    }
                }
                else if (sipRequest.Body.Contains("Number="))
                {
                    string tag = sipRequest.Body.Split("Tag=")[1].Split(";")[0];
                    string number = sipRequest.Body.Split("Number=")[1].Split(";")[0];
                    for (int i = 0; i < sessionCount; i++)
                    {
                        if (session[i].sessionTag == tag)
                        {
                            if (session[i].remoteNumber2 == "") session[i].remoteNumber2 = number;
                            else if (session[i].remoteNumber3 == "") session[i].remoteNumber3 = number;
                            break;
                        }
                    }
                }
            };
        }

        public static void ReadConfig()
        {
            string path = Application.StartupPath + "\\config.txt";
            string[] lines = System.IO.File.ReadAllLines(path);
            for (int i = 0; i < lines.Length; i++)
            {
                string[] items = lines[i].Split('=');
                switch (items[0])
                {
                    case "sipUser":
                        sipUser = items[1];
                        break;
                    case "sipPassword":
                        sipPassword = items[1];
                        break;
                    case "sipServerUri":
                        sipServerUri = lines[i].Substring("sipServerUri=".Length);
                        break;
                    case "sipProxyUri":
                        sipProxyUri = lines[i].Substring("sipProxyUri=".Length);
                        break;
                    case "expiry":
                        expiry = int.Parse(items[1]);
                        break;
                    case "sipSignUpUrl":
                        sipSignUpUrl = items[1];
                        break;
                    case "sipUserOut":
                        sipUserOut = items[1];
                        break;
                    case "sipPasswordOut":
                        sipPasswordOut = items[1];
                        break;
                    case "sipServerUriOut":
                        sipServerUriOut = lines[i].Substring("sipServerUriOut=".Length);
                        break;
                    case "sipProxyUriOut":
                        sipProxyUriOut = lines[i].Substring("sipProxyUriOut=".Length);
                        break;
                    case "expiryOut":
                        expiryOut = int.Parse(items[1]);
                        break;
                    case "sipSignUpUrlOut":
                        sipSignUpUrlOut = items[1];
                        break;
                }
            }
        }


        public static void AgentSetFree(string agentNumber,string message)
        {
            // 如果不存在，则添加
            int i;
            for (i = 0; i < agentCount; i++)
            {
                if (agent[i].agentNumber == agentNumber)
                {
                    break;
                }
            }
            if (i == agentCount)
            {
                if (agentCount < agent.Length)
                {
                    agent[agentCount].agentNumber = agentNumber;
                    agent[agentCount].status = "Free";
                    agentCount++;
                    sip?.AddFreeAgent(agentNumber, "", "", "");
                }
            }
            // 如果存在，则更新
            else
            {
                // 从Session中读取remoteNumber
                for (int j = 0; j < sessionCount; j++)
                {
                    if (session[j].agentNumber == agentNumber)
                    {
                        agent[i].status = "Free";
                        agent[i].lastCall1 = session[j].remoteNumber1;
                        agent[i].lastCall2 = session[j].remoteNumber2;
                        agent[i].lastCall3 = session[j].remoteNumber3;
                        if (message.Contains("LastMessage="))
                        {
                            agent[i].lastMessage = message.Split("LastMessage=")[1].Split("EndLasterMessage")[0];
                        }
                        //MessageBox.Show("Agent " + agentNumber +"|"+ agent[i].status + "|Last Call 1: " + agent[i].lastCall1 + "|Last Call 2: " + agent[i].lastCall2 + "|Last Call 3: " + agent[i].lastCall3);
                        for (int k = j; k < sessionCount - 1; k++)
                        {
                            session[k] = session[k + 1];
                        }
                        sessionCount--;
                        sip?.AddFreeAgent(agentNumber, agent[i].lastCall1, agent[i].lastCall2, agent[i].lastCall3);
                        break;
                    }
                }
            }
            Show();
        }

        private static void Show()
        {
            ACD acd = Application.OpenForms.OfType<ACD>().FirstOrDefault();
            if (acd == null) return;
            acd.Show();
        }
    }
}
